<template>
  <div class="app-container">
    <el-card class="box-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <el-icon class="header-icon"><Folder /></el-icon>
            <span class="header-title">商品分类管理</span>
          </div>
          <el-button type="primary" :icon="Plus" @click="() => handleAdd()">新增分类</el-button>
        </div>
      </template>
      
      <el-tree
        ref="treeRef"
        :data="categoryTree"
        :props="defaultProps"
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
        class="category-tree"
      >
        <template #default="{ node, data }">
          <div class="custom-tree-node">
            <div class="node-left">
              <div class="category-icon-wrapper">
                <el-image 
                  v-if="data.icon" 
                  :src="data.icon" 
                  fit="contain" 
                  class="category-icon"
                  :preview-src-list="[data.icon]"
                  :preview-teleported="true"
                >
                  <template #error>
                    <div class="image-slot">
                      <el-icon><Picture /></el-icon>
                      <span>暂无图片</span>
                    </div>
                  </template>
                </el-image>
                <div v-else class="image-slot">
                  <el-icon><Picture /></el-icon>
                  <span>暂无图片</span>
                </div>
              </div>
              <div class="node-content">
                <span class="node-label">{{ node.label }}</span>
                <div class="node-info">
                  <el-tag size="small" type="info" effect="plain">层级: {{ data.level }}</el-tag>
                  <el-tag size="small" type="info" effect="plain" v-if="data.sort">排序: {{ data.sort }}</el-tag>
                </div>
              </div>
            </div>
            <div class="node-right">
              <el-tag 
                size="small" 
                :type="data.status === 1 ? 'success' : 'info'"
                effect="light"
                class="status-tag"
              >
                {{ data.status === 1 ? '正常' : '禁用' }}
              </el-tag>
              <div class="operation-buttons">
                <el-tooltip content="新增子分类" placement="top">
                  <el-button
                    type="primary"
                    link
                    :icon="Plus"
                    @click="() => handleAdd(data.id)"
                  />
                </el-tooltip>
                <el-tooltip content="修改分类" placement="top">
                  <el-button
                    type="primary"
                    link
                    :icon="Edit"
                    :disabled="data.id === 0"
                    @click="() => handleEdit(data.id)"
                  />
                </el-tooltip>
                <el-tooltip content="删除分类" placement="top">
                  <el-button
                    type="danger"
                    link
                    :icon="Delete"
                    :disabled="data.id === 0"
                    @click="() => handleDelete(data.id)"
                  />
                </el-tooltip>
              </div>
            </div>
          </div>
        </template>
      </el-tree>
    </el-card>

    <!-- 添加或修改分类对话框 -->
    <el-dialog
      :title="title"
      v-model="open"
      width="500px"
      append-to-body
      destroy-on-close
      class="category-dialog"
    >
      <el-form
        ref="categoryRef"
        :model="form"
        :rules="rules"
        label-width="80px"
        class="category-form"
      >
        <el-form-item label="上级分类" prop="parentId">
          <el-tree-select
            v-model="form.parentId"
            :data="categoryTree"
            :props="defaultProps"
            placeholder="请选择上级分类"
            check-strictly
            :render-after-expand="false"
            class="tree-select"
            @change="handleParentChange"
          >
            <template #default="{ node, data }">
              <span>{{ data.id === 0 ? '顶级分类' : data.name }}</span>
            </template>
          </el-tree-select>
        </el-form-item>
        <el-form-item label="分类名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入分类名称" />
        </el-form-item>
        <el-form-item label="层级" prop="level">
          <el-input-number v-model="form.level" :min="1" :max="3" :disabled="true" />
          <span class="level-tip">（根据上级分类自动计算）</span>
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <image-upload 
            v-model="form.icon" 
            :is-show-tip="false"
          />
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="form.sort" :min="0" :max="999" controls-position="right" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :value="1">
              <el-icon><CircleCheck /></el-icon>
              正常
            </el-radio>
            <el-radio :value="0">
              <el-icon><CircleClose /></el-icon>
              禁用
            </el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 图标预览对话框 -->
    <el-dialog
      v-model="previewOpen"
      title="图标预览"
      width="300px"
      append-to-body
      destroy-on-close
    >
      <div class="icon-preview">
        <img v-if="form.icon" :src="form.icon" class="preview-image" />
        <div v-else class="no-image">暂无图标</div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Plus, 
  Edit, 
  Delete, 
  Folder, 
  Picture,
  CircleCheck,
  CircleClose,
  View
} from '@element-plus/icons-vue'
import { getCategoryTree, addCategory, updateCategory, delCategory, getCategory } from '@/api/product/category'
import type { CategoryVO, CategoryForm } from '@/api/product/category/types'
import ImageUpload from '@/components/ImageUpload/index.vue'
import type { UploadFile } from 'element-plus'

const categoryTree = ref<CategoryVO[]>([])
const open = ref(false)
const previewOpen = ref(false)
const title = ref('')
const treeRef = ref()

const defaultProps = {
  children: 'children',
  label: 'name',
  value: 'id'
}

const form = ref<CategoryForm>({
  name: '',
  parentId: 0,
  level: 1,
  icon: '',
  sort: 0,
  status: 1
})

/** 表单重置 */
const reset = () => {
  form.value = {
    name: '',
    parentId: 0,
    level: 1,
    icon: '',
    sort: 0,
    status: 1
  }
}

const rules = {
  name: [
    { required: true, message: '分类名称不能为空', trigger: 'blur' }
  ],
  parentId: [
    { required: true, message: '上级分类不能为空', trigger: 'change' }
  ],
  level: [
    { required: true, message: '层级不能为空', trigger: 'change' }
  ]
}

const fileList = ref<UploadFile[]>([])

/** 查询分类树 */
const getTree = async () => {
  try {
    const response = await getCategoryTree()
    categoryTree.value = [{
      id: 0,
      name: '顶级分类',
      parentId: 0,
      level: 0,
      children: response.data
    }]
  } catch (error) {
    console.error('获取分类树失败:', error)
  }
}

/** 处理上级分类变更 */
const handleParentChange = (value: number) => {
  if (value === 0) {
    form.value.level = 1
  } else {
    const findParentLevel = (tree: CategoryVO[], id: number): number => {
      for (const node of tree) {
        if (node.id === id) {
          return node.level
        }
        if (node.children) {
          const level = findParentLevel(node.children, id)
          if (level !== -1) {
            return level
          }
        }
      }
      return -1
    }
    
    const parentLevel = findParentLevel(categoryTree.value[0].children || [], value)
    form.value.level = Math.min(parentLevel + 1, 3)
  }
}

/** 查找父节点 */
const findParentNode = (tree: CategoryVO[], id: number): CategoryVO | null => {
  for (const node of tree) {
    if (node.id === id) {
      return node
    }
    if (node.children) {
      const found = findParentNode(node.children, id)
      if (found) {
        return found
      }
    }
  }
  return null
}

/** 处理图标变更 */
const handleIconChange = (value: string) => {
  if (value) {
    fileList.value = [{
      name: 'category-icon',
      url: value,
      status: 'success',
      uid: Date.now()
    }]
  } else {
    fileList.value = []
  }
}

/** 查找节点 */
const findNode = (tree: CategoryVO[], id: number): CategoryVO | null => {
  for (const node of tree) {
    if (node.id === id) {
      return node
    }
    if (node.children) {
      const found = findNode(node.children, id)
      if (found) {
        return found
      }
    }
  }
  return null
}

/** 新增按钮操作 */
const handleAdd = (parentId?: number) => {
  reset()
  if (parentId !== undefined) {
    form.value.parentId = parentId
    handleParentChange(parentId)
  }
  open.value = true
  title.value = '添加分类'
}

/** 修改按钮操作 */
const handleEdit = async (id: number) => {
  if (id === 0) {
    ElMessage.warning('不能修改顶级分类')
    return
  }
  
  reset()
  try {
    const response = await getCategory(id)
    form.value = response.data
    open.value = true
    title.value = '修改分类'
  } catch (error) {
    console.error('获取分类信息失败:', error)
  }
}

/** 提交按钮 */
const submitForm = async () => {
  try {
    if (form.value.id) {
      await updateCategory(form.value)
      ElMessage.success('修改成功')
    } else {
      await addCategory(form.value)
      ElMessage.success('新增成功')
    }
    open.value = false
    getTree()
  } catch (error) {
    console.error('提交失败:', error)
  }
}

/** 删除按钮操作 */
const handleDelete = async (id: number) => {
  if (id === 0) {
    ElMessage.warning('不能删除顶级分类')
    return
  }
  
  try {
    await ElMessageBox.confirm('是否确认删除该分类？', '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await delCategory(id)
    ElMessage.success('删除成功')
    getTree()
  } catch (error) {
    console.error('删除分类失败:', error)
  }
}

/** 取消按钮 */
const cancel = () => {
  open.value = false
  form.value = {
    name: '',
    parentId: 0,
    level: 1,
    icon: '',
    sort: 0,
    status: 1
  }
}

/** 预览图标 */
const previewIcon = () => {
  if (form.value.icon) {
    previewOpen.value = true
  } else {
    ElMessage.warning('请先上传图标')
  }
}

onMounted(() => {
  getTree()
})
</script>

<style scoped>
.app-container {
  padding: 20px;
  min-height: calc(100vh - 120px);
  background-color: var(--el-bg-color-page);
}

.box-card {
  border-radius: 8px;
  height: 100%;
  transition: all 0.3s;
}

.box-card:hover {
  box-shadow: var(--el-box-shadow-light);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 50px;
  padding: 0 20px;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-icon {
  font-size: 28px;
  color: var(--el-color-primary);
}

.header-title {
  font-size: 20px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.category-tree {
  margin-top: 16px;
  min-height: calc(100vh - 250px);
  padding: 0 20px;
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding: 16px 0;
  height: 60px;
  border-bottom: 1px solid var(--el-border-color-lighter);
}

.custom-tree-node:last-child {
  border-bottom: none;
}

.node-left {
  display: flex;
  align-items: center;
  gap: 16px;
  height: 100%;
}

.category-icon-wrapper {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  overflow: hidden;
  background-color: var(--el-fill-color-light);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.category-icon-wrapper:hover {
  transform: scale(1.05);
}

.category-icon {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.node-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.node-label {
  font-weight: 500;
  font-size: 15px;
  color: var(--el-text-color-primary);
}

.node-info {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

.level-tip {
  margin-left: 8px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.node-right {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 100%;
}

.status-tag {
  min-width: 60px;
  text-align: center;
  height: 24px;
  line-height: 24px;
  border-radius: 12px;
}

.operation-buttons {
  display: flex;
  gap: 12px;
  height: 100%;
  align-items: center;
}

.image-slot {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--el-text-color-secondary);
  font-size: 12px;
  background-color: var(--el-fill-color-light);
}

.image-slot .el-icon {
  font-size: 20px;
  margin-bottom: 4px;
}

.category-dialog :deep(.el-dialog__body) {
  padding: 24px 32px;
}

.category-form {
  max-width: 460px;
  margin: 0 auto;
}

.tree-select {
  width: 100%;
}

.dialog-footer {
  text-align: right;
  padding-top: 24px;
  height: 60px;
}

.icon-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 240px;
  background-color: var(--el-fill-color-light);
  border-radius: 4px;
}

.preview-image {
  max-width: 100%;
  max-height: 240px;
  object-fit: contain;
}

.no-image {
  color: var(--el-text-color-secondary);
  font-size: 14px;
}

:deep(.el-radio) {
  margin-right: 20px;
  height: 32px;
  line-height: 32px;
}

:deep(.el-radio__label) {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 100%;
}

:deep(.el-form-item) {
  margin-bottom: 24px;
}

:deep(.el-input-number) {
  width: 180px;
}

:deep(.el-tree-node__content) {
  height: 60px;
}

:deep(.el-button) {
  height: 32px;
  padding: 0 16px;
}

:deep(.el-button--small) {
  height: 24px;
  padding: 0 12px;
}

:deep(.el-dialog__header) {
  margin: 0;
  padding: 20px 32px;
  border-bottom: 1px solid var(--el-border-color-light);
}

:deep(.el-dialog__footer) {
  padding: 16px 32px;
  border-top: 1px solid var(--el-border-color-light);
}

:deep(.el-tree-node__content:hover) {
  background-color: var(--el-fill-color-light);
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: var(--el-color-primary-light-9);
}

:deep(.el-input-number.is-disabled .el-input-number__decrease),
:deep(.el-input-number.is-disabled .el-input-number__increase) {
  border-color: var(--el-border-color);
  color: var(--el-text-color-regular);
}

:deep(.el-input-number.is-disabled .el-input__wrapper) {
  background-color: var(--el-fill-color-light);
}

.icon-upload-wrapper {
  display: flex;
  align-items: center;
  gap: 16px;
}

.preview-button {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 32px;
}

.preview-button .el-icon {
  font-size: 16px;
}
</style> 